home *** CD-ROM | disk | FTP | other *** search
/ BMUG Revelations / BMUG Revelations.toast / Utilities / Network / QUE / Basic / mail.h next >
Text File  |  1989-10-01  |  10KB  |  555 lines

  1. /*
  2. ------------------------------------------------------------
  3. Copyright ) 1989 Rob Kassel, Mike McCandless and the Massachusetts Institute of Technology
  4.  
  5. Permission to use, copy, modify, and distribute this software and its documentation for any purpose without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission.  The authors and M.I.T. make no representations about the suitability of this software for any purpose.  It is provided Ras isS without express or implied warranty.
  6. ------------------------------------------------------------
  7. */
  8.  
  9. #include "ctype.h"
  10. #include "fcntl.h"
  11. #include "errno.h"
  12. #include "sys/types.h"
  13. #include "sys/stat.h"
  14. #include "string.h"
  15. #include "dirent.h"
  16. #include "stdio.h"
  17. #include "memory.h"
  18.  
  19.  
  20.  
  21. /*quemail's constants*/
  22.  
  23. #define MAXMSGLENGTH 20000    /*Characters long before it is divided...*/
  24.  
  25. #define aYearInS 31536000
  26. #define MAXNAME 255
  27. #define aFROM "From:"
  28. #define aRPLTO "Reply-To:"
  29. #define SUBJECT "Subject:"
  30. #define theDir "/usr/maildrops"
  31. #define theSpace " \0"
  32. #define MSGHDR "m"
  33. #define FALSE 0
  34. #define TRUE !0
  35. #define dropChar 'd'
  36. #define userChar 'u'
  37. #define MAXLINE 1000
  38.  
  39. #define spcl    1       /*special char: @ . , */
  40. #define atm     2       /*an atom; just a word, etc*/
  41. #define cmnt    3       /*a comment in ()'s*/
  42. #define addrS   4       /*like this: <akjdk.adkfj@kjdf.asfd>*/
  43. #define atAtm   5       /*like this: kajsdfjasdjf.asdkfl@kajsflk.ajsdlfj*/
  44. #define colAtm  6       /*like this: alkdjfljas dflsajf:lajsfjfja*/
  45. #define commaAtm 7    /*A comma, alone and single*/
  46.  
  47.  
  48. /*getmsg constants*/
  49.  
  50.  
  51.  
  52. #define TOREAD "readMsg"
  53. #define MSGHDR "m"
  54.  
  55.  
  56.  
  57. struct fld {
  58.         int cnt;                /*Holds the number of items found in field*/
  59.         char buf[MAXLINE];      /*Holds the orig. text of field*/
  60.         struct fldItem {
  61.                 char *txt;
  62.                 int tpe;
  63.         }       itm[50];         /*Holds each item description*/
  64. };
  65.  
  66.  
  67. /*Memory module for storing text stuff*/
  68.  
  69.  
  70. struct memBuf {
  71.   int segSze;
  72.   int maxSegs;
  73.   int curSeg;
  74.   char **memPtrs;
  75.   char *curPtr;
  76.   char *playBackPtr;
  77.   int playBackSeg;
  78. } *allocBuf();
  79.     
  80.  
  81. /*String routines*/
  82.  
  83. char *getline(),*flp(),*fltr();
  84. char *alcCh();
  85. char *makeLower(),*rmSpce();
  86. char *strchr();
  87. char *getNextFile();
  88. char *readAdress(),*formatIt();
  89. char *alter(),*interpret();
  90. char errBuf[200];
  91. char *parseReplyTo(),*encode();
  92. char *strp1Ch();
  93. char *hdrLnPtrs[MAXLINE];
  94. char *sys_errlist[];
  95. char *getPtr(),*calloc();
  96. int errno;
  97.  
  98. FILE *fopen();
  99. long time();
  100.  
  101.  
  102. char *getline(s,n)
  103.  
  104. char *s;
  105. int n;
  106. {
  107.         int c;
  108.         char *cs;
  109.  
  110.         cs = s;
  111.         while (--n > 0 && (c = getchar()) != EOF)
  112.                 if((*cs++ = c) == '\n')
  113.                         break;
  114.         if (n<=0)
  115.                 printf("Data lost: line > %d characters.\n",n);
  116.  
  117.         *cs = '\0';
  118.         return((c == EOF && cs == s) ? NULL : s);
  119. }
  120.  
  121. char* flp(s)
  122.  
  123. char* s;
  124.  
  125. {
  126. int x,lp;
  127. char* c;
  128.  
  129. x = strlen(s);
  130. c = (char*) malloc(x * sizeof(char));
  131. if (c == NULL) {
  132.         sprintf(errBuf,"Out of memory.\n");
  133.         errorParser(errBuf);
  134. }
  135.  
  136. for(lp=0;lp<x;lp++)
  137.         c[lp] = s[x - lp - 1];
  138.  
  139.  
  140. c[x] = 0;
  141. return(c);
  142. }
  143.  
  144.  
  145. char* fltr(s)
  146.  
  147. char *s;
  148. {
  149. int x,lp;
  150.  
  151. x = strlen(s);
  152. for(lp=0;lp<x;lp++)
  153.         if (*(s + lp) == '.' || *(s + lp) == '/')
  154.                 *(s + lp) = '0';
  155.  
  156. return(s);
  157. }
  158.  
  159.  
  160.  
  161. char* rmSpce(s)
  162.  
  163. char *s;
  164. {
  165. char *m;
  166.  
  167. m = alcCh(strlen(s));
  168. strcpy(m,s);
  169.  
  170. while(*m == (char)32 || *m == (char) 9 || *m == (char) 10)
  171.         m++;
  172.  
  173. while(*(m + strlen(m) - 1) == (char) 32 || *(m + strlen(m) - 1) == (char) 9 || *
  174. (m + strlen(m) - 1) == (char) 10)
  175.         *(m + strlen(m) - 1) = 0;
  176.  
  177.  
  178. return(m);
  179. }
  180.  
  181.  
  182. char* makeLower(s)
  183.  
  184. char *s;
  185. {
  186. int x,lp;
  187.  
  188. x = strlen(s);
  189. for (lp = 0; lp < x; lp++)
  190.         if (isupper(*(s + lp)))
  191.                 *(s + lp) = tolower(*(s + lp));
  192. return(s);
  193. }
  194.  
  195. int fileThere(name)
  196.  
  197. char *name;
  198.  
  199. {
  200. DIR *dirp;
  201. struct dirent *dp;
  202.  
  203. dirp = opendir(".");
  204. if (dirp == NULL) {
  205.     sprintf(errBuf,"Can't open directory.");
  206.     errorParser(errBuf);
  207. }
  208.  
  209. for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp))
  210.     if (!strcmp(dp->d_name, name)) {
  211.          closedir (dirp);
  212.          return(1);
  213.     }
  214.  
  215. closedir (dirp);
  216. return(0);
  217. }
  218.  
  219.  
  220. char* alter(buf,theC)
  221.  
  222. char *buf;
  223. char theC;
  224.  
  225. {
  226. char ch,c;
  227. char *pBuf;
  228. char buf2[MAXLINE],*pBuf2;
  229. char buf3[MAXLINE + 5];
  230. int aSpce;
  231. int n,x,y;
  232.  
  233. pBuf = buf;
  234. n = 0;
  235.  
  236. pBuf = (char*) rmSpce(buf);
  237.  
  238. x = strlen(pBuf);
  239. y = 0;
  240.  
  241. while(y < x) {
  242.         if (*(pBuf + y) == (char) 9 ||  *(pBuf + y) == (char) 10)
  243.                 *(pBuf + y) = (char) 32;
  244.         y++;
  245. }
  246.  
  247. y = 0;
  248. c = 0;
  249. aSpce = FALSE;
  250. pBuf2 = buf2;
  251.  
  252. while (y < x) {
  253.         if (*(pBuf + y) != 32) {
  254.                 *(pBuf2 + c) = *(pBuf + y);
  255.                 c++;
  256.                 aSpce = FALSE;
  257.         }
  258.         else
  259.                 if (!aSpce) {
  260.                         *(pBuf2 + c) = *(pBuf + y);
  261.                         aSpce = TRUE;
  262.                         c++;
  263.                 }
  264.         y++;
  265. }
  266.  
  267. *(pBuf2 + c) = 0;
  268.  
  269.  
  270. y = 0;
  271. x = strlen(pBuf2);
  272.  
  273. while (y < x)  {
  274.         if (*(pBuf2 + y) == ' ')   *(pBuf2 + y) = theC;
  275.         y++;
  276. }
  277.  
  278. if (*(pBuf2 + strlen(pBuf2) - 1) == ':') *(pBuf2 + strlen(pBuf2) - 1) = '\0';
  279. return(pBuf2);
  280. }
  281.  
  282.  
  283.  
  284.  
  285. errorParser(msg)
  286.  
  287. char *msg;
  288.  
  289. {
  290. fprintf(stderr,"%s\n",msg);
  291. exit(1);
  292.  
  293. /*This must complain about the error, save the message as best it can, and*/
  294. /*exit; terminate with extreme prejudice*/
  295. }
  296.  
  297.  
  298. fieldParse(pF)
  299.  
  300. struct fld *pF;
  301.  
  302. {
  303. /*This procedure will be given all the text after the : in an unfolded line*/
  304. /*It must decipher it into its constituent parts*/
  305.  
  306. char *m;
  307. int cnt,cnt2,lp,touched;
  308. char ch;
  309.  
  310.  
  311. m = rmSpce(pF->buf);
  312. cnt = 0;
  313.  
  314. while (*m != '\0') {
  315.         touched = FALSE;
  316.  
  317.         if (*m == 40) {
  318.                 touched = TRUE;
  319.                 pF->itm[cnt].txt = (char*) (m + 1);
  320.                 pF->itm[cnt].tpe = cmnt;
  321.                 cnt++;
  322.                 m++;
  323.                 while(TRUE) {
  324.                         ch = *m;
  325.                         if (ch == (char)41 || ch == (char)0)
  326.                                 break;
  327.                         m++;
  328.                 }
  329.  
  330.                 if (*m == 0) {
  331.                         printf("Unbalanced paren.\n");
  332.                         exit(1);
  333.                 }
  334.                 if (*m == 41)
  335.                         *m = '\0';
  336.                 m++;
  337.         if (*m == ',') {
  338.             pF->itm[cnt].txt = '\0';
  339.             pF->itm[cnt].tpe = commaAtm;
  340.             m+=1;
  341.         }
  342.         }
  343.  
  344.         if (*m == 60) {
  345.                 touched = TRUE;
  346.                 pF->itm[cnt].txt = (char*) (m + 1);
  347.                 pF->itm[cnt].tpe = addrS;
  348.                 cnt++;
  349.                 m++;
  350.                 while(TRUE) {
  351.                         ch = *m;
  352.                         if (ch == (char)62 || ch == (char)0)
  353.                                 break;
  354.                         m++;
  355.                 }
  356.  
  357.                 if (*m == 0) {
  358.                         printf("Unbalanced paren.\n");
  359.                         exit(1);
  360.                 }
  361.                 if (*m == 62)
  362.                         *m = '\0';
  363.                 m++;
  364.         if (*m == ',') {
  365.             pF->itm[cnt].txt = '\0';
  366.             pF->itm[cnt].tpe = commaAtm;
  367.             m+=1;
  368.         }
  369.     }
  370.  
  371.         if (!touched && !(*m == 32 || *m == 9)) {
  372.                 touched = TRUE;
  373.                 pF->itm[cnt].txt = (char*) m;
  374.                 pF->itm[cnt].tpe = atm;
  375.                 cnt++;
  376.                 m++;
  377.                 while(TRUE) {
  378.                         ch = *m;
  379.                         if (ch == (char)32 || ch == (char)0 || ch ==(char) 9)
  380.                                 break;
  381.                         m++;
  382.                         if (ch == '@' || ch == '!')
  383.                                 pF->itm[cnt - 1].tpe = atAtm;
  384.                 }
  385.  
  386.                 if (*m == 32 || *m == 9)
  387.                         *m = '\0';
  388.                 m++;
  389.         }
  390.  
  391.         if (!touched)
  392.                 m++;
  393. }
  394.  
  395. pF->cnt = cnt;
  396. }
  397.  
  398.  
  399. char* alcCh(sze)
  400.  
  401. int sze;
  402.  
  403. {
  404. char *p;
  405.  
  406. p = (char*) malloc(sze * sizeof(char));
  407. if (p==NULL) {
  408.     sprintf(errBuf,"Out of memory.");
  409.     errorParser(errBuf);
  410. }
  411. else
  412.     return(p);
  413. }
  414.  
  415.  
  416. char* strp1Ch(s)
  417.  
  418. char *s;
  419.  
  420. {
  421. *(s + strlen(s) - 1) = '\0';
  422. return(s);
  423. }
  424.  
  425.  
  426.  
  427.  
  428. /*Memory managament procedures...*/
  429.  
  430. resetBuf(theBuf)
  431.  
  432. struct memBuf *theBuf;
  433.  
  434. {
  435.   theBuf->playBackPtr = theBuf->memPtrs[0];
  436.   theBuf->playBackSeg = 0;
  437. }
  438.  
  439.  
  440.  
  441.  
  442.  
  443. struct memBuf *allocBuf(segSze,maxSegs)
  444.  
  445. int segSze,maxSegs;
  446.  
  447. {
  448. struct memBuf *thePtr;
  449.  
  450.  
  451. thePtr = (struct memBuf *) getPtr(sizeof(struct memBuf));
  452. thePtr->maxSegs = maxSegs;
  453. thePtr->segSze = segSze;
  454. thePtr->memPtrs = (char**) getPtr(maxSegs*sizeof(char*));
  455. thePtr->curSeg = 0;
  456. thePtr->memPtrs[0] = getPtr(segSze);
  457. thePtr->curPtr = thePtr->memPtrs[0];
  458. thePtr->playBackPtr = thePtr->curPtr;
  459. thePtr->playBackSeg = 0;
  460.  
  461. return(thePtr);
  462. }
  463.  
  464.  
  465.  
  466.  
  467. storeStr(str,bufPtr)
  468.  
  469. char *str;
  470. struct memBuf *bufPtr;
  471.  
  472. {
  473. int lng = strlen(str) + 1;
  474. int charR;
  475.  
  476.  
  477. while (lng > 0) {
  478.   charR = bufPtr->segSze - (bufPtr->curPtr - bufPtr->memPtrs[bufPtr->curSeg]);
  479.  
  480.   if (lng < charR) {
  481.     strcpy(bufPtr->curPtr,str);
  482.     bufPtr->curPtr += lng;
  483.     break;
  484.   }
  485.  
  486.   if (lng == charR) {
  487.     strcpy(bufPtr->curPtr,str);
  488.     bufPtr->curSeg++;
  489.     bufPtr->memPtrs[bufPtr->curSeg] = getPtr(bufPtr->segSze);
  490.     bufPtr->curPtr = bufPtr->memPtrs[bufPtr->curSeg];
  491.     break;
  492.   }
  493.   
  494.   if (lng > charR) {
  495.     strncpy(bufPtr->curPtr,str,charR);
  496.     lng -= charR;
  497.     str += charR;
  498.     bufPtr->curSeg++;
  499.     bufPtr->memPtrs[bufPtr->curSeg] = getPtr(bufPtr->segSze);
  500.     bufPtr->curPtr = bufPtr->memPtrs[bufPtr->curSeg];
  501.   }
  502. }
  503.  
  504. return(1);
  505. }
  506.  
  507.  
  508.  
  509.  
  510. readStr(buf,bufPtr)
  511.  
  512. char *buf;
  513. struct memBuf *bufPtr;
  514.  
  515. {
  516. char *tP=buf;
  517. char *trackP = bufPtr->playBackPtr;
  518.  
  519.  
  520. if (*trackP == 0) {
  521.   *buf = 0;
  522.   return(0);
  523. }
  524.  
  525. while (*trackP != 0) {
  526.   *tP++ = *trackP++;
  527.   if (trackP == bufPtr->memPtrs[bufPtr->playBackSeg] + bufPtr->segSze) {
  528.     bufPtr->playBackSeg++;
  529.     trackP = bufPtr->memPtrs[bufPtr->playBackSeg];
  530.   }
  531. }
  532.  
  533. *tP = 0;
  534. bufPtr->playBackPtr = trackP+1;
  535. return(1);
  536. }
  537.  
  538.  
  539.  
  540. char *getPtr(sze)
  541.  
  542. int sze;
  543.  
  544. {
  545. char *ptr;
  546.  
  547. ptr = calloc(sze,sizeof(char));
  548.  
  549. if (ptr == NULL) {
  550.     errorParser("Out of memory.\n");
  551.     exit(1);
  552. }
  553. return(ptr);
  554. }
  555.